/-------------------------------------------\
|                 SF3KtoProT                |
| Star Fighter 3000 to ProTracker convertor |
|          (C) Chris Bazley, 2009           |
|        Version 0.01 (02 Jun 2009)         |
\-------------------------------------------/
N.B. This text is best viewed at a display width of 77 columns.

-----------------------------------------------------------------------------
 1   Introduction and Purpose
     ========================

  'Star Fighter 3000' is a three dimensional flying shoot-em-up game which
was first published in 1994 for 32-bit Acorn RISC OS computers. This program
converts the music tracks from their original esoteric file format
(understood only by the game's own music player) into standard Amiga
ProTracker V1.1B song/module format. Most of the original features of the
music can be replicated fairly accurately in ProTracker format.

  The game's own music and sound effects player is a relocatable module named
'SFX_Handler'. For brevity, I have referred to it by that name throughout the
remainder of this manual.
-----------------------------------------------------------------------------
2   Requirements
    ============

  The supplied executable file will only work on RISC OS machines. It has
not been tested on any version of RISC OS earlier than 3.7, although it
should also work on earlier versions provided that a 'SharedCLibrary' module
is active. It is known to be compatible with 32 bit versions of RISC OS.

  You will obviously require a copy of the game 'Star Fighter 3000' from
which to rip the music. Until release 2.02 of the game, the sound sample data
and music tracks were incorporated into 'SFX_Handler'. You need a version
where this data is instead supplied in separate files. For example, they are
included in the free upgrade patch to version 3.08:
http://starfighter.acornarcade.com/download/uni308.zip

  Compressed music data files can be found inside the !Star3000 application,
in the sub-directory named "Music". Raw sound sample data files suitable for
used with this program are located in the sub-directory "Samples".

-----------------------------------------------------------------------------
3   Quick Guide
    ===========

  Ensure that the !Star3000 application has been 'seen' by the Filer, so that
the system variable Star3000$Dir has been set.

  Hold down the Shift key and double-click on the !Star3000 application to
open it. Copy the supplied 'index' file into the sub-directory that contains
sound sample data files (as !Star3000.Samples.index). This file should
require no modification because it has been tailored for the game (which
configures 'SFX_Handler' using similar parameters).

  Set the current selected directory to that containing the 'SF3KtoProT'
program. On RISC OS 6, that can be done by opening the relevant directory
display and choosing 'Set work directory' from the menu (or giving the window
input focus and then pressing F11).

  Press Ctrl-F12 to open a task window and then invoke the music conversion
program using the following command:

  *SF3KtoProT -v <Star3000$Dir>.Music.BonusLevel <Star3000$Dir>.Samples

  This should convert the Star Fighter 3000 music file 'BonusLevel' into
ProTracker format, using sound samples taken from the 'Samples' directory
inside the !Star3000 application. The '-v' switch enables verbose output,
which shows what is happening during the conversion process. Because no
output filename was specified, the ProTracker file will have been saved in
the same directory as the input file, under a variation of the same name (in
this case as !Star3000.Music.BonusLevel/mod).

  By varying the second argument to the 'SF3KtoProT' program, any of the
other files in the !Star3000.Music directory can also be converted to
ProTracker format.

  If the Filer has already 'seen' an application which claims file type
&CC5 ('TeqMusic' - allocated to Krisalis) then you should simply be able to
double-click on the output files in order to play the music. If that causes
an error box saying "An application that loads a file of this type has not
been found by the Filer" then you must explicitly load a tracker player such
as DigitalCD or Digital Symphony, before dragging the output file to the
player's iconbar icon.

-----------------------------------------------------------------------------
4   Detailed guide
    ==============

4.1 Command line syntax
    -------------------
  SF3KtoProT [switches] <music-file> <samples-dir>

Switches (names may be abbreviated):
  -allowsfx           Allow notes to be played using sound effect samples
  -blankend           Append a blank pattern to the end of the song
  -channelglissando   Restrict glissando effects to the same channel
  -extraoctaves       Utilise non-standard ProTracker octaves 0 and 4
  -fastglissando      Fast glissandos (contiguous Tone Portamento commands)
  -help               Show version number and usage guide
  -indexfile <file>   Index file to use instead of looking in <samples-dir>
  -outfile <file>     Specify a name for the output file
  -verbose or -debug  Emit debug output

4.2 Files and directories
    ---------------------
  When invoking 'SF3KtoProT', you must specify both the name of the
compressed music file to be converted and the name of a directory containing
the sound samples to be incorporated in the output ProTracker file. Unlike
ProTracker files, SF3000 music files do not incorporate sound samples (which
makes sense given that each piece uses a subset of the same instruments).
Suitable sound samples are supplied with the game, inside the
!Star3000.Samples directory.

  Because the sound sample files consist of raw data in 16 bit little-endian
signed linear format, there is nowhere to keep meta data. Rather than hard-
wiring the tuning value, repeat offset and type of each sample into the
conversion program, it reads this data from an index file (the format of
which is described in section 7.3). By default, it looks for an index file in
the same directory as the sample files, but you can force it to look
elsewhere by using the '-indexfile' switch. That may be useful if the game is
on read-only media such as a CD-ROM.

4.3 Sound effects
    -------------
  Early versions of the 'SFX_Handler' module automatically blocked sound
effects whilst playing music. That distinction was made on the basis of the
sample type; sample numbers 0 to 11 are classified as effects whereas 12 to
22 are classified as instruments (surprisingly, 'Radio' is included in the
latter category).

  This restriction was removed in version 2.10 of 'SFX_Handler' (distributed
with release 2.02 of the game), because it didn't make any sense in the
context of a configurable number of channels (only 4 of which are used for
music). Doing so revealed hitherto inaudible parts of the 'Intro1' music
- notes played using the 'Wind' and 'TextBeep' samples. The extra notes were
stripped out prior to release 2.04 of the game, to restore the track's
original ambience.

  The samples index file ('-indexfile' switch) specifies the type of each
sample. The command line switch '-allowsfx' has been provided to allow
inclusion in the output file of notes played using samples designated as
sound effects. By default, such notes are stripped out when converting to
ProTracker format. This option is only likely to be useful if you have
access to music files from an older version of SF3000.

4.4 End of song
    -----------
  Like most tracker music players, 'SFX_Handler' stops abruptly upon reaching
the last division of the pattern that was played at the final song position.
It cuts off any notes that are still playing, instead of allowing the samples
to finish playing (and perhaps repeat).

  This policy means that notes triggered late in the final pattern won't
actually be audible! For example, the final division of the last pattern of
the 'GameOver' music contains commands to play the 'String' sample at low
pitch on channels 0 and 2. These notes would round the tune off nicely, but
they are never heard in the game.

  If the command line switch '-blankend' is specified then an additional
'blank' pattern will be created in the output file and the play order
modified so that this extra pattern is played last, thus allowing late notes
to be heard. If the pattern played immediately beforehand contains glissando
effects (not yet overridden by new notes on the same channel) then the
so-called 'blank' pattern may actually contain Tone Portamento commands to
ensure that these glissandos reach their target pitch.

4.5 Glissando effects
    -----------------
  An idiosyncrasy of 'SFX_Handler' is that glissando effects are applied to
all channels playing the sample mapped to the voice number specified by bits
16-19 of the channel data. In other words, if two channels are playing the
same sample then a glissando effect for that sample number will cause their
pitches to converge on a common value. The reason is that glissandos are
implemented using the SFX_Pitch SWI, which doesn't take a channel number as a
parameter (unlike SFX_Force, which is used to play notes).

  The command line switch '-channelglissando' can be used to restrict
glissando effects to the channel on which the command was issued. The
difference between the two modes of conversion is most obvious with the
'Intro1' music, where the final high note played on channel 4 is either held
or else slides towards the same target pitch as a note on channel 3.

  In a ProTracker file, glissando effects must be explicitly continued by
a series of Tone Portamento commands throughout their expected duration,
whereas 'SFX_Handler' continues to update the pitch of a note automatically
until its target pitch is reached or it is usurped by another note on the
same channel. That makes conversion between the two formats more awkward.

  Each Tone Portamento command incorporates a value to govern the pitch slide
speed. Even the minimum speed of '1' is noticeably faster than the rate of
change when playing music through the 'SFX_Handler' module. (In early
versions of 'SFX_Handler', the increment in the phase accumulator pitch
oscillator value was updated at the start of alternate buffer fills, which
meant the slide speed was dependent upon the configured buffer size!)

  By default, 'SF3KtoProT' interleaves Tone Portamento commands with Normal
Play commands, which effectively halves the minimum pitch slide speed of 1.
That behaviour can be disabled by specifying switch '-fastglissando', in
which case it will instead output contiguous Tone Portmento commands.
ProTracker files generated using this switch will be 'cleaner' but any
glissandos will reach their target pitch more quickly than the same music
played through 'SFX_Handler'.

4.6 ProTracker octave range
    -----------------------
  The standard ProTracker pitch range is 3 octaves, whereas Star Fighter
3000's music format allows a range of 8 octaves (because 3 bits of channel
data are allocated for the octave number).

  After applying the tuning values to the default set of SF3000 samples, it
can be heard that octave numbers in a SF3000 music track are exactly one
higher than in a ProTracker file. However, some of the tuning values are very
large: 'String', 'BassHeavy', 'DrumHeavy' and 'HiHat' are tuned up by at
least one octave and 'Piano' is tuned down by nearly a whole octave!

  The following table shows the range of octave numbers actually used by each
of the music tracks supplied with Star Fighter 3000:

             Untuned  Tuned  ProTracker
  Track name Min Max Min Max Min Max
  ---------- --- --- --- --- --- ---
  BonusLevel  2   5   2   4   1   3
  FlightDem1  2   4   2   4   1   3
  FlightDem2  2   6   3   5   2   4*
  GameOver    1   3   1   3   0*  2
  GameStart   2   3   2   4   1   3
  HighScore   2   5   2   5   1   4*
  Intro1      1   4   1   4   0*  3
  MissionCom  2   5   2   4   1   3
  Toccatta    1   5   1   5   0*  4*
  TopScore    1   6   1   5   0*  4*

  It can be seen that 'GameOver', 'Intro1', 'Toccatta' and 'TopScore' contain
notes which are too low to be represented within the standard ProTracker
octave range 1 to 3. Conversely, 'FlightDem2', 'HighScore', 'Tocatta', and
'TopScore' contain notes that are too high - even after certain samples have
been tuned down.

  The default solution adopted by 'SF3KtoProT' is to pre-tune certain
ProTracker samples to a higher or lower octave than the original audio data.
Hence, the output file may contain several different samples generated from
the same source (e.g. 'TopScore/mod' contains samples named 'BassLight-R0-O0'
and 'BassLight-R0-O-1' - the latter specifically for low notes).

  Andrew Scott gives a table of period values for a range of five octaves
rather than the standard three. However, this comes with the caveat that
octaves 0 and 4 are non-standard, unlike octaves 1 to 3. Some trackers may be
unable to play notes which use those periods, or might even crash! However,
Andre Timmermans's 'TimPlayer' module (for RISC OS) seems to cope.

  The command line switch '-extraoctaves' has been provided to enable use
of these non-standard period values in preference to generating alternative
versions of samples pre-tuned to a higher or lower octave. (The conversion
routine falls back to generating pre-tuned samples for notes that would be
more than one octave outside the standard range.)

-----------------------------------------------------------------------------
6   How it works
    ============

  Firstly, the SF3000 music track to be converted to ProTracker format is
loaded into memory and the sound sample definitions are read from the index
file. Then, the music is converted in two passes:

  The purpose of the first pass is merely to determine which samples (and
variants thereof) need to be included in the ProTracker file. Only commands
to play notes are examined; glissandos are ignored, as are any notes played
using samples designated as sound effects (unless '-allowsfx' was specified).

  For each play note command, the sample's tuning value is converted to the
nearest whole semitone and used to adjust the octave and note numbers. At
this stage it becomes clear whether or not the final octave number will be
within the standard ProTracker range (or extended range, if '-extraoctaves'
was specified), and hence whether a version of the sample pre-tuned to a
higher or lower octave will be required.

  Because the ProTracker format does not provide any facility to loop a
sample a specific number of times (unlike 'SFX_Handler'), a separate version
of each sample will be needed for every distinct number of repeats.

  If creation of a ProTracker sample with the required number of repeats and
level of pre-tuning has not already been scheduled then a new entry is added
to the list of ProTracker samples to be created. This list is later used to
write the sample information table at the head of the output file.

  The purpose of second pass is to transcode the pattern data from SF3000 to
ProTracker format.

  To generate glissando effects, the transcode routine must keep track of
which sample (if any) is believed to be playing on each channel, and the
target pitch if a glissando is affecting that channel. This record is reset
before transcoding each pattern - which isn't foolproof, but is the best that
can be done given that patterns may be played in any order.

  Each individual division of every pattern is also examined in two passes in
order to ensure that glissando effects are applied consistently across all
four channels (unless '-channelglissando' was specified):

  The first pass discovers any glissando effects and updates the virtual
channel state accordingly. The octave and note numbers which specify the
target pitch are converted to their ProTracker equivalents using the same
technique as before. However, this time the ProTracker sample has already
been chosen for each channel and the transcode routine must compensate for
the fact that different variants of the same basic sample (all affected by a
glissando effect) may have been pre-tuned to different octaves. The final
target octave for some channels may be outside the valid range, but nothing
can be done except outputting a warning and substituting a nearer octave.

  The second pass actually writes the appropriate ProTracker commands for
the division being transcoded: a Tone Portamento or Normal Play command if
there is no note play command in the SF3000 music data (or the sample number
is undefined); otherwise a Set Volume command to play the specified note. In
the former case, the virtual channels state is consulted to determine whether
a glissando is in progress, and to ensure that only the first Tone Portamento
command in the sequence specifies the sample number and target pitch.

  Immediately after transcoding the pattern to be played last (as specified
by the play order), a snapshot of the virtual channels state is taken to
allow continuation of any glissando effects on the additional 'blank' pattern
(if one is to be appended).

  Finally, the list of ProTracker samples awaiting creation is used to copy
audio data from the relevant files into the output file. Because the format
of the source data is 16 bit, whereas it is 8 bit in a ProTracker file, the
least significant bytes are discarded (the first of each pair, because the
data is little-endian).

  If the number of repeats for a sample is greater than 0 and less than 15
then the audio data between the repeat offset and the end of the file will be
duplicated the requisite number of times. It is expedient to treat 15 as 'loop
forever', because that is the only kind of repeats supported by the ProTracker
format, and this keeps the output file size reasonable.

  Some of the ProTracker samples may need to be pre-tuned to a higher or lower
octave than the original audio data. That is done crudely by doubling (or
quadrupling) each sample value to lower the pitch by one (or two) octaves.
Alternatively it skips one of every two (or three out of four) sample values
to raise the pitch by one (or two) octaves.

-----------------------------------------------------------------------------
7   File formats
    ============

7.1 Music track file
    ----------------
  Until release 2.02 of Star Fighter 3000, the music tracks were incorporated
directly into the 'SFX_Handler' module. In later releases, they were instead
supplied as individual files containing the same data but encoded using
Fednet's esoteric lossless compression algorithm (with file type &154).

  The first 4 bytes of a compressed file give the expected size of the data
when decompressed, as a 32 bit signed little-endian integer. Gordon Key's file
decompression module 'FDComp', which is presumably normative, rejects input
files where the top bit of the fourth byte is set (i.e. negative values).

  Thereafter, the compressed data consists of tightly packed groups of 1, 8
or 9 bits without any padding between them or alignment with byte boundaries.
A decompressor must deal with two main types of chunk: The first (load a
byte) consists of 1+8 bits, and the second (copy data within output buffer)
consists of 1+9+8 or 1+9+9 bits.

The type of each chunk is determined by whether its first bit is set:

0.   Decode the next 8 bits of the input file (0-255) and write them as a
   byte at the current output position. The fact that this directive requires
   9 bits to represent 8 bits of information explains the inflation that can
   occur when attempting to compress random data.

1.   Decode the next 9 bits of the input file, which give an offset (0-511)
   within the data already decompressed, relative to a point 512 bytes behind
   the current output position. If this offset is greater than or equal to
   256 (i.e. within the last 256 bytes written) then decode the next 8 bits,
   which give the number of bytes (0-255) to be copied to the current output
   position. Otherwise, the next 9 bits give the number of bytes to be copied
   (0-511).

    If the read pointer is before the start of the output buffer then zeros
  should be written at the output position until it becomes valid again. This
  is a legitimate method of initialising areas of memory with zeros.

    A quirk of 'FDComp' is that least 1 byte is always written. That is
  probably a bug, although a well-written compressor should not insert
  directives to copy 0 bytes anyway. Note also that it isn't possible to
  replicate the whole of the preceding 512 bytes in one operation.

  The table below shows the Star Fighter 3000 music data format, after the
contents of the file have been decompressed:

Header:
  Offset  Data
  +0      Tempo (metronome value in centiseconds, 0-255)
  +1...   Unused
  +16...  16 byte table mapping voice numbers to sample numbers
    +16     Sample number to use for voice 0
    +17     Sample number to use for voice 1
    +18     Sample number to use for voice 2 ...etc
  +32     Number of patterns in file - 1
  +36...  Unused
  +40...  64 byte play order for patterns (terminated by 255)
  +104... Patterns data (see format below)
    +104... 1024 bytes of data for pattern 0
    +1128.. 1024 bytes of data for pattern 1
    +2152.. 1024 bytes of data for pattern 2 ...etc

  The value at offset +32 is supposedly a 32 bit word, and probably signed
little-endian. However, there is no evidence to corroborate that because
'SFX_Handler' doesn't actually use this value. Patterns numbered higher than
254 would be inaccessible anyway because of the format of the play order.

Pattern:
  Offset  Data
  +0...   16 bytes of data for division 0
  +16...  16 bytes of data for division 1
  +32...  16 bytes of data for division 2
  ...
  +1008.. 16 bytes of data for division 63

Division:
  Offset  Data
  +0...   Channel 1 data (0 for none)
  +4...   Channel 2 data (0 for none)
  +8...   Channel 3 data (0 for none)
  +12...  Channel 4 data (0 for none)

Channel data:
  Offset  Data
  +0      Bits 0-3: Note number (in semitones, 0 to 11)
          Bits 4-7: Unused
  +1      Bits 0-3: Octave number (0 to 7)
          Bits 4-7: Linear volume (0 to 15)
  +2      Bits 0-3: Voice number (0 to 15)
          Bits 4-7: Action (0 none, 1 play, or 2 glissando)
  +3      Bits 0-3: Unused
          Bits 4-7: Number of repeats (0 to 15)

  The sample number to be used is looked up from the specified voice number
using the voice table in the header.

  If action > 1 then a glissando effect is triggered, sliding all instances
of the specified sample towards the specified pitch. The volume and repeats
parameters of such commands are ignored.

  Otherwise a note is forced on the channel, using the specified sample,
volume, pitch and repeats parameters.

7.2 Sound sample file
    -----------------
  Until release 2.02 of Star Fighter 3000, all of the instruments and sound
effects required by the game were incorporated directly into the 'SFX_Handler'
module in mono 8 bit Archimedes VIDC format (similar to mu-law).

  In later releases, the sound samples were instead supplied as individual
files containing raw audio data in mono 16 bit little-endian signed linear
format. This is better suited to the sound hardware in modern RISC OS machines
and would make it possible to substitute equivalent sound samples with a
greater dynamic range.

7.3 Sound samples index file
    ------------------------
  The set of sound samples to be used when transcoding music to ProTracker
format is defined by an index file in plain ASCII text format. This file
also defines items of metadata related to each sample.

  Each line of text is either a comment (preceded by '#', which MUST be the
first character on that line), a blank line (which consists of nothing but
whitespace), or a sample definition (which may have leading and/or trailing
whitespace). Sample definitions consist of a numeric ID to be assigned to
the sample, the name of a file from which to read raw sample data, an offset
from which to repeat the sample (for sustained notes), the type of sample
(music or effect), and a tuning value to correct the pitch when playing
music.

  Sample numbers must lie within the range 0-255, because of the voice table
format in a SF3000 music track. The range of sample numbers assigned by a
sample index file needn't be contiguous, nor do the samples need to be
defined to be ascending numeric order. Any sample numbers which are still
undefined when transcoding music will merely cause warning messages. However,
the sample index file parser does fault attempts to assign the same sample
number more than once.

  The repeat offset must be less than the length of the sample data, when
both have been rounded down to the nearest even number (the ProTracker file
format isn't capable of representing odd sample lengths). Remember that the
repeat offset is the number of sample values to skip, whereas the file size
is in bytes (each 16 bit sample occupies two bytes).

  The sample type is represented by a single letter which may be either upper
or lower case: "M" for music or "E" for effect. The significance of the
sample type is explained in section 4.3 'Sound Effects'.

  The magnitude of the tuning value must be small enough that the calculation
to convert it to ProTracker tuning units does not overflow a 'long' integer.
On RISC OS, the largest value representable by a 'long' integer is one less
than 2 to the power of 31, which means that tuning values must lie within the
range -22369599, 22369599 (1048575 octaves).

  The grammar of a samples index file is as follows (in BackusNaur Form):

  <file>       ::= { <line> }*
  <line>       ::= <comment> | <noncomment>
  <comment>    ::= '#' { <comchar> }* <eol>
  <noncomment> ::= <spc> [ <id> <spc> <filename> <spc> <repeat>
                           <spc> <type> <spc> <tuning> <spc> ] <eol>
  <id>         ::= <number>
  <filename>   ::= <fnchar> { <fnchar> }*
  <repeat>     ::= <number>
  <type>       ::= "E" | "e" | "M" | "m"
  <tuning>     ::= [ "-" ] <number>
  <comchar>    ::= any character except <eol>
  <fnchar>     ::= any character except <eol>, <tab> or " "
  <spc>        ::= { " " | <tab> }*
  <tab>        ::= character code 9
  <eol>        ::= character code 10
  <integer>    ::= <digit> { <digit> }*
  <digit>      ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

  Note that <fnchar> must also be a valid character for use in a file name
on the host platform. On RISC OS, FileCore-based filing systems such as ADFS
reserve the following characters for wildcards and other special uses: '*',
'#', '$', '@', '^', '%' and '\'.

-----------------------------------------------------------------------------
8   Program history
    ==============

0.01 (02 Jun 2009)

  First public release.

-----------------------------------------------------------------------------
9   Compiling the program
    =====================

  Full source code is supplied with this program. To compile and link the
code without modification you will also require an ISO 9899:1999 standard 'C'
library (as supplied with recent versions of the Acorn C/C++ Development
Suite).

  The supplied 'Make' file was automatically generated by Acorn's Make
application, and will attempt to invoke the Norcroft RISC OS ARM C compiler
and ARM linker supplied with the Acorn C/C++ Development Suite. To reduce
external dependencies, it is set up to compile code compatible with floating
point emulator 2 and link against RISCOS Ltd's generic stubs library
('StubsG').

  If you wish to port this program to another platform then you should only
need to modify the functions defined in platform.c, which is intended to
contain all of the platform-specific code. For example, the set_file_type()
function should probably just be a stub which does nothing. Other functions
such as find_leaf() and append_ext() should be modified to use the
appropriate directory name and file extension separator characters (e.g. '\'
and '.' on DOS/Windows, instead of '.' and '/' on RISC OS).

-----------------------------------------------------------------------------
10  Licence and Disclaimer
    ======================

  This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public Licence as published by the Free
Software Foundation; either version 2 of the Licence, or (at your option)
any later version.

  This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licence for
more details.

  You should have received a copy of the GNU General Public Licence along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.

-----------------------------------------------------------------------------
11  Credits
    =======

  SF3KtoProT was designed and programmed by Christopher Bazley with
additional ideas, testing and suggestions by Martin Bazley.

  Much credit goes to David O'Shea and Keith McKillop for working out the
Fednet compression algorithm. The decompression code incorporated in this
program is heavily based (with permission) upon the DeComp module that David
wrote for the Stunt Racer 2000 track designer.

  Most of my information on the Amiga ProTracker file format came from a
document relating to Digital Symphony, a multi-tasking sound tracker editor
for RISC OS which was marketed by Oregan Developments. That description is
(C) 1992/1996 Bernard Jungen and Gil Damoiseaux (members of BASS). See
http://users.skynet.be/Andre.Timmermans/digitalcd/player/docs.zip (in
sub-directory Docs/DSymPlay within the archive).

  I gleaned additional information from Andrew Scott's Noisetracker/
Soundtracker/Protracker module format specification (with credit to Lars
Hamre, Norman Lin, Mark Cox, Peter Hanning, Steinar Midtskogen, Marc Espie
and Thomas Meyer). That document is available here:
http://mediasrv.ns.ac.yu/extra/fileformat/modules/mod/mod-form.txt

  The game Star Fighter 3000 is (C) FEDNET Software 1994, 1995. Sound &
music for the game was by A. M. Perrins.

-----------------------------------------------------------------------------
12  Contact details
    ===============

  Feel free to contact me with any bug reports, suggestions or anything else.
Even if you think that my programs are crap, I'll be interested to know!

  Mail:  Mr C.J. Bazley
         139 Church End
         Cambridge
         CB1 3LF

  Email: mailto:cs99cjb@gmail.com

  WWW:   http://starfighter.acornarcade.com
         http://kingfishercorner.eu
